package me.sdevil507.supports.shiro.realm;

import me.sdevil507.org.dto.OrgResourceRelDto;
import me.sdevil507.org.po.OrgUserPo;
import me.sdevil507.org.service.OrgRoleService;
import me.sdevil507.org.service.OrgUserService;
import me.sdevil507.supports.shiro.MySimpleByteSource;
import me.sdevil507.supports.shiro.enums.LoginChannel;
import me.sdevil507.supports.shiro.enums.LoginModeType;
import me.sdevil507.supports.shiro.enums.RoleType;
import me.sdevil507.supports.shiro.helper.OrgAccountHelper;
import me.sdevil507.supports.shiro.realms.BaseAuthorizingRealm;
import me.sdevil507.supports.shiro.token.UsernamePasswordToken;
import me.sdevil507.supports.status.ComConstant;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 后台管理用户认证授权相关，类似dataSource，负责用户账户验证，获取所持有的角色<br>
 * 继承AuthorizingRealm（授权），其继承了AuthenticatingRealm即身份验证），<br>
 * 而且也间接继承了CachingRealm（带有缓存实现）
 *
 * @author sdevil507
 */
public class OrgUsernamePasswordRealm extends BaseAuthorizingRealm {

    @Autowired
    private OrgUserService orgUserService;

    @Autowired
    private OrgRoleService orgRoleService;

    /**
     * 定义realm名称
     *
     * @return realm名称
     */
    @Override
    public String getName() {
        return LoginChannel.ORG.name() + ":" + LoginModeType.USERNAME_PASSWORD.name();
    }

    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof UsernamePasswordToken;
    }

    /**
     * 返回对应用户所拥有的授权信息
     *
     * @param principals 账号信息集合
     * @return 授权信息
     * @see SimpleAuthorizationInfo
     */
    @Override
    public AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        authorizationInfo.setStringPermissions(orgRoleService.findPermissions());
        return authorizationInfo;
    }

    /**
     * 根据用户名，执行相关的验证操作
     *
     * @param token 验证token
     * @return 身份验证信息
     * @throws AuthenticationException 身份验证异常
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

        String username = (String) token.getPrincipal();

        OrgUserPo orgUserPo = null;

        try {
            orgUserPo = orgUserService.readOneByPhoneNumber(username);
        } catch (Exception e) {
            e.printStackTrace();
        }

        // 用户名不存在
        if (orgUserPo == null) {
            throw new UnknownAccountException();
        }

        // 账号被锁定(true:锁定,false:未锁定)
        if (orgUserPo.getLocked()) {
            throw new LockedAccountException();
        }
        // 如果身份认证验证成功，返回一个AuthenticationInfo实现；
        return new SimpleAuthenticationInfo(orgUserPo.getPhoneNumber(),
                orgUserPo.getPassword(),
                getName()
        );
    }
}
